package com.hczt.xhminiapp.appapi.resolver;

import com.hczt.xhminiapp.common.bean.CodeMsg;
import com.hczt.xhminiapp.common.bean.Constants;
import com.hczt.xhminiapp.common.exception.BizException;
import com.hczt.xhminiapp.common.redis.BasePrefix;
import com.hczt.xhminiapp.common.redis.RedisService;
import com.hczt.xhminiapp.db.entity.Doctor;
import com.hczt.xhminiapp.db.entity.Patient;
import com.hczt.xhminiapp.db.repository.DoctorRepository;
import com.hczt.xhminiapp.db.repository.PatientRepository;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.MethodParameter;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.support.WebDataBinderFactory;
import org.springframework.web.context.request.NativeWebRequest;
import org.springframework.web.method.support.HandlerMethodArgumentResolver;
import org.springframework.web.method.support.ModelAndViewContainer;

import javax.servlet.http.HttpServletRequest;

/**
 * @author 红创-马海强
 * @date 2019-03-07 18:32
 * @description 自定义方法参数解析器，封装当前操作者对象
 */
@Component
public class CurrentUserArgumentResolver implements HandlerMethodArgumentResolver {

    @Autowired
    private RedisService redisService;

    @Autowired
    private DoctorRepository doctorRepository;

    @Autowired
    private PatientRepository patientRepository;

    @Override
    public boolean supportsParameter(MethodParameter methodParameter) {
        return methodParameter.getParameterType().equals(CurrentDoctor.class);
    }

    @Override
    public Object resolveArgument(MethodParameter methodParameter, ModelAndViewContainer modelAndViewContainer, NativeWebRequest nativeWebRequest, WebDataBinderFactory webDataBinderFactory) throws Exception {
        HttpServletRequest request = nativeWebRequest.getNativeRequest(HttpServletRequest.class);
        String openId = request.getHeader("token");
        String role = request.getHeader("role");
        BasePrefix prefix;
        if(Constants.DOCTOR.equalsIgnoreCase(role)) {
            prefix = new BasePrefix(Constants.RedisKey.DOCTOR_USER_INFO);
            CurrentDoctor currentDoctor = redisService.get(prefix, openId, CurrentDoctor.class);
            if(currentDoctor == null){
                Doctor doctor = doctorRepository.findByOpenidAndDeletedIsFalse(openId);
                if(null == doctor) {
                    throw new BizException(CodeMsg.OPENID_ROLE_NO_MATCH);
                }
                currentDoctor = new CurrentDoctor();
                BeanUtils.copyProperties(doctor, currentDoctor);
                redisService.set(prefix, openId, currentDoctor);
                return currentDoctor;
            }
        } else if(Constants.PATIENT.equalsIgnoreCase(role)) {
            prefix = new BasePrefix(Constants.RedisKey.PATIENT_USER_INFO);
            CurrentPatient currentPatient = redisService.get(prefix, openId, CurrentPatient.class);
            if(currentPatient == null){
                Patient patient = patientRepository.findByOpenidAndDeletedIsFalse(openId);
                if(null == patient) {
                    throw new BizException(CodeMsg.OPENID_ROLE_NO_MATCH);
                }
                currentPatient = new CurrentPatient();
                BeanUtils.copyProperties(patient, currentPatient);
                redisService.set(prefix, openId, currentPatient);
                return currentPatient;
            }
        }
        return null;
    }
}
